package com.meisupic.copyright.support;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 功能说明：pdf文档转图片 第三方依赖：pdfbox-2.0.8.jar <dependency> <groupId>org.apache.pdfbox</groupId>
 * <artifactId>pdfbox</artifactId> <version>2.0.8</version> </dependency>
 *
 * @return <br/> 修改历史：<br/> 1.[2018年01月08日 上午11:56] 创建方法 by guyi
 */
@Component
public class PdfToImage {

  private static final Logger LOGGER = LoggerFactory.getLogger(PdfToImage.class);

  private static final String PAGE_INDEX_SEPARATOR = ",";

  /**
   * pdf转图片
   *
   * @param srcFile pdf转换源文件
   * @param destFile 图片输出目标路径，为空时默认源文件所在的文件夹
   * @param format 待输出图片的格式，默认jpg
   * @param dpi 分辨率，默认96
   * @param merge 是否合并为一张，默认为每页生成一张图片
   */
  public void pdfToImage(File srcFile, File destFile
      , String format, Float dpi, Boolean merge) throws IOException {
    List<BufferedImage> images = pdfToImage(srcFile, dpi == null ? 96f : dpi);
    if (images == null || images.isEmpty()) {
      return;
    }
    //默认为jpg
    format = format == null || format.isEmpty() ? "jpg" : format;
    //合并多张图片为一张
    merge = merge == null ? false : merge;
    if (merge) {
      BufferedImage image = mergeImages(images);
      images.clear();
      images.add(image);
    }
    //保存到本地
    for (int i = 0, len = images.size(); i < len; i++) {
      //输出格式: [文件夹路径]/[pdf文件名]_0001.jpg
      ImageIO.write(images.get(i), format, destFile);
    }
  }

  private BufferedImage mergeImages(List<BufferedImage> images) {
    int width = 0, height = 0;
    for (BufferedImage image : images) {
      width = image.getWidth() > width ? image.getWidth() : width;
      height += image.getHeight();
    }
    BufferedImage pdfImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = pdfImage.createGraphics();
    height = 0;
    for (BufferedImage image : images) {
      g2d.drawImage(image, (width - image.getWidth()) / 2, height, image.getWidth(),
          image.getHeight(), null);
      height += image.getHeight();
    }
    g2d.dispose();
    return pdfImage;
  }

  private List<BufferedImage> pdfToImage(File file, float dpi) throws IOException {
    List<BufferedImage> imgList = null;
    PDDocument pdDocument = null;
    BufferedImage image;
    try {
      pdDocument = PDDocument.load(file);
      PDFRenderer renderer = new PDFRenderer(pdDocument);
      int numPages = pdDocument.getNumberOfPages();
      imgList = new ArrayList<BufferedImage>();
      for (int i = 0; i < numPages; i++) {
        image = renderer.renderImageWithDPI(i, dpi);
        if (null != image) {
          imgList.add(image);
        }
      }
    } catch (IOException e) {
      LOGGER.error("convert pdf pages to images failed.", e);
      //FIXME
      throw e;
    } finally {
      try {
        if (null != pdDocument) {
          pdDocument.close();
        }
      } catch (IOException e) {
        LOGGER.error("close IO failed when convert pdf pages to images.", e);
        //FIXME
        throw e;
      }
    }
    return imgList;
  }

}